﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace AfterlifeLib.Levels
{
    /// <summary>
    /// Een layer voor tile data
    /// </summary>
    public class TileLayer : Layer
    {
        /// <summary>
        /// De tileset die de layer gebruikt
        /// </summary>
        private Texture2D tileset = null;
        public Texture2D Tileset
        {
            get { return tileset; }
            set
            {
                if (value != null)
                    tileset = value;
            }
        }

        public TileLayer()
            : base()
        {

        }

        public TileLayer(int[,] values)
            : base(values)
        {
            
        }

        public TileLayer(int width, int height)
            : base(width, height)
        {
            TotalFill(-1);
        }

        /// <summary>
        /// Verkrijg een source rectangle door middel van een index
        /// </summary>
        /// <param name="tilesetWidth">De breedte van de tileset</param>
        /// <param name="tilesetHeight">De hoogte van de tilset</param>
        /// <param name="index">De index van de tile in de tileset</param>
        /// <returns></returns>
        public static Rectangle GetSourceRectangle(int tilesetWidth, int index)
        {
            if (index == -1 || index == 0)
                return new Rectangle(
                    0,
                    0,
                    Level.TileWidth,
                    Level.TileHeight);

            int x = index % (tilesetWidth / Level.TileWidth);
            int y = index / (tilesetWidth / Level.TileWidth);

            return new Rectangle(
                x * Level.TileWidth, 
                y * Level.TileHeight, 
                Level.TileWidth, 
                Level.TileHeight);
        }

        /// <summary>
        /// Verkrijgt een index door middel van een source rectangle (Microsoft.Xna.Framework.Rectangle
        /// </summary>
        /// <param name="tilesetWidth">De breedte van de tileset</param>
        /// <param name="tilesetHeight">De hoogte van de tilset</param>
        /// <param name="rect">De source rectangle in de tileset</param>
        /// <returns></returns>
        public static int GetRectangleIndex(int tilesetWidth, Microsoft.Xna.Framework.Rectangle rect)
        {
            int indexX = rect.X / Level.TileWidth;
            int indexY = (rect.Y / Level.TileHeight) * (tilesetWidth / Level.TileWidth);
            
            return indexX + indexY;
        }

        /// <summary>
        /// Verkrijgt een index door middel van een source rectangle (System.Drawing.Rectangle)
        /// </summary>
        /// <param name="tilesetWidth">De breedte van de tileset</param>
        /// <param name="tilesetHeight">De hoogte van de tilset</param>
        /// <param name="rect">De source rectangle in de tileset</param>
        /// <returns></returns>
        public static int GetRectangleIndex(int tilesetWidth, System.Drawing.Rectangle rect)
        {
            int indexX = rect.X / Level.TileWidth;
            int indexY = (rect.Y / Level.TileHeight) * (tilesetWidth / Level.TileWidth);

            return indexX + indexY;
        }

        /// <summary>
        /// Teken de layer op het scherm (Game)
        /// </summary>
        /// <param name="spriteBatch">De SpriteBatch om mee te tekenen</param>
        /// <param name="camera">De Camera om de positie van de tiles te bepalen</param>
        public void Draw(SpriteBatch spriteBatch, Camera2D camera)
        {
            int startX = camera.IntX / Level.TileDrawWidth;
            int startY = camera.IntY / Level.TileDrawHeight;

            int endX = startX + (Camera2D.ScreenWidth / Level.TileDrawWidth) + 2;
            int endY = startY + (Camera2D.ScreenHeight / Level.TileDrawHeight) + 2;

            spriteBatch.Begin();
            {
                for (int x = startX; x < endX; x++)
                {
                    if (x < 0 || x >= Width)
                        break;

                    for (int y = startY; y < endY; y++)
                    {
                        if (y < 0 || y >= Height)
                            break;

                        if (Values[y, x] == -1)
                            continue;

                        spriteBatch.Draw(
                            tileset,
                            new Rectangle(
                                x * Level.TileDrawWidth - camera.IntX,
                                y * Level.TileDrawHeight - camera.IntY,
                                Level.TileDrawWidth,
                                Level.TileDrawHeight),
                            GetSourceRectangle(Tileset.Width, Values[y, x]),
                            Color.White);
                    }
                }
            }
            spriteBatch.End();
        }

        /// <summary>
        /// Teken de layer op het scherm (Editor)
        /// </summary>
        /// <param name="spriteBatch">De SpriteBatch om mee te tekenen</param>
        /// <param name="camera">De Camera om de positie van de tiles te bepalen</param>
        /// <param name="tileReplacement">Een Texture2D die in de plaats van een lege plek word getekent</param>
        public void EditorDraw(SpriteBatch spriteBatch, Camera2D camera, Texture2D tileReplacement, bool drawGrid)
        {
            spriteBatch.Begin();
            {
                for (int x = 0; x < Width; x++)
                {
                    for (int y = 0; y < Height; y++)
                    {
                        if (Values[y, x] == -1)
                        {
                            if (drawGrid)
                            {
                                spriteBatch.Draw(
                                    tileReplacement,
                                    new Rectangle(
                                    x * Level.TileDrawWidth - camera.IntX,
                                    y * Level.TileDrawHeight - camera.IntY,
                                    Level.TileDrawWidth,
                                    Level.TileDrawHeight),
                                null,
                                Color.White);
                            }
                        }
                        else
                        {
                            spriteBatch.Draw(
                                Level.Tileset,
                                new Rectangle(
                                    x * Level.TileDrawWidth - camera.IntX,
                                    y * Level.TileDrawHeight - camera.IntY,
                                    Level.TileDrawWidth,
                                    Level.TileDrawHeight),
                                GetSourceRectangle(Level.Tileset.Width, Values[y, x]),
                                Color.White);
                        }
                    }
                }
            }
            spriteBatch.End();
        }
    }
}
